/*
 * Copyright (c) 2018-2999 湖南洛云网络科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.SkuRetailParam;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.util.Arith;
import com.yami.shop.dao.*;
import com.yami.shop.service.OrderRetailProdLogService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.SkuService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author LGH
 * @date 2020-08-29 09:05:44
 */
@Service
@AllArgsConstructor
public class OrderRetailProdLogServiceImpl extends ServiceImpl<OrderRetailProdLogMapper, OrderRetailProdLog> implements OrderRetailProdLogService {

    private final OrderRetailProdLogMapper orderRetailProdLogMapper;
    private final RetailProdMapper retailProdMapper;
    private final SkuMapper skuMapper;
    private final SkuService skuService;
    private final ProductMapper productMapper;
    private final ProductService productService;
    private final SkuRetailMapper skuRetailMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<OrderRetailProdLog> returnStocksByOrderNumber(String orderNumber) {
        // 查询出下单的记录，还原库存，然后删除下单记录
        List<OrderRetailProdLog> list = orderRetailProdLogMapper.selectByOrderNumber(orderNumber);
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        List<Long> ids = new ArrayList<>();
        list.forEach(i->{
            retailProdMapper.returnStocks(i.getRetailProdId(),i.getNum());
            ids.add(i.getRetailProdId());
        });
        // 更新库存商品sku库存，和商品库存
        updateRetainProdRelationSkuAndProdStock(ids);
        // 将还原回去后的记录删除
        int a = orderRetailProdLogMapper.updateByOrderNumber(orderNumber);
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean returnStocksByRetailProdIds(List<Long> ids) {
        updateRetainProdRelationSkuAndProdStock(ids);
        return true;
    }

    @Override
    public List<OrderRetailProdLog> selectByOrderNumber(String orderNumber) {
        return orderRetailProdLogMapper.selectByOrderNumber(orderNumber);
    }


    /**
     * @param ids 更新的记录
     */
    private void updateRetainProdRelationSkuAndProdStock(List<Long> ids) {
        // 将所有相关的单品查询出来，然后根据单品的数量，以及sku的组合单品,更新sku的库存，prod的库存
        if (CollectionUtils.isEmpty(ids)){
            return;
        }
        // 获取单品列表
        List<RetailProd> retailProds = retailProdMapper.selectBatchIds(ids);
        Map<Long, RetailProd> retailProdMap = retailProds.stream().collect(Collectors.toMap(RetailProd::getRetailProdId, (k) -> k));
        List<Sku> skus = new ArrayList<>();

        List<SkuRetail> skuRetails = skuRetailMapper.getByRetailProdId(ids);
        // 获取与单品相关的sku的所有skuRetails
        List<SkuRetail> skuRetailsAll = skuRetailMapper.getAllByRetailProdId(ids);
        Map<Long, List<SkuRetail>> retailsAll = skuRetailsAll.stream().collect(Collectors.groupingBy(SkuRetail::getSkuId));

        Map<Long, List<SkuRetail>> listMap = skuRetails.stream().collect(Collectors.groupingBy(SkuRetail::getSkuId));
        listMap.forEach((skuId,lists) ->{
            Sku sku = new Sku();
            sku.setSkuId(skuId);
            List<Integer> skuStocks = new ArrayList<>();
            lists.forEach(k->{
                sku.setProdId(k.getProdId());
                // 需要单独查询
                RetailProd retailProd = retailProdMap.get(k.getRetailProdId());
                // 修改后某个单品可以组合多少组
                int a = new Double(Math.floor(Arith.div(retailProd.getStocks(), k.getRetailNums()))).intValue();
                // 然后和其他的sku的单品 进行比较
                List<SkuRetail> skuRetails1 = retailsAll.get(skuId);
                skuRetails1.forEach(i->{
                    if (Objects.equals(i.getRetailProdId(),k.getRetailProdId())) {
                        return;
                    }
                    skuStocks.add(i.getStocks());
                });
                skuStocks.add(a);
            });
            sku.setStocks(Collections.min(skuStocks));
            skus.add(sku);
            // 清除缓存
            skuMapper.updateStocksById(sku);
            skuService.removeSkuCacheBySkuIdAndLang(skuId,sku.getProdId(), LanguageEnum.LANGUAGE_ZH_CN.getLang());
            skuService.removeSkuCacheBySkuIdAndLang(skuId,sku.getProdId(),LanguageEnum.LANGUAGE_EN.getLang());
        });

        Map<Long, List<Sku>> prods = skus.stream().collect(Collectors.groupingBy(Sku::getProdId));
        prods.forEach((prodId,skuList) ->{
            Product product = new Product();
            product.setProdId(prodId);
            product.setTotalStocks(skuList.stream().collect(Collectors.summingInt(Sku::getStocks)));
            productMapper.updateStocksById(product);
            productService.removeProductCacheByProdId(prodId);
            productService.removeProdCacheByProdId(prodId,LanguageEnum.LANGUAGE_ZH_CN.getLang());
            productService.removeProdCacheByProdId(prodId,LanguageEnum.LANGUAGE_EN.getLang());
        });
    }

}
